package com.wyh.service.serviceImpl.feemanagementserviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wyh.domain.dto.feemanagementdto.*;
import com.wyh.domain.po.feemanagementpo.Billes;
import com.wyh.domain.po.feemanagementpo.Billdetailes;
import com.wyh.domain.po.feemanagementpo.Invoicerecordes;
import com.wyh.domain.po.feemanagementpo.PaymentRecords;
import com.wyh.domain.vo.feemanagementvo.*;
import com.wyh.mapper.feemanagementmapper.BillMapper;
import com.wyh.service.feemanagementservice.BillService;
import com.wyh.service.feemanagementservice.BillsService;
import com.wyh.service.feemanagementservice.PaymentRecordsService;
import com.wyh.service.feemanagementservice.PaymentmethodService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class BillServiceImpl extends ServiceImpl<BillMapper, Billes> implements BillService{

    @Autowired
    private BillMapper billMapper;

    private final BillsService billsService;

    private final PaymentRecordsService paymentRecordsService;


    @Override
    public BillsVO selectAllBills(String account, BilDTO bilDTO) {
        // 初始化分页插件，设置当前页码和每页显示的记录数
        PageHelper.startPage(bilDTO.getPage(),bilDTO.getPageSize());
        // 查询所有账单信息，这里未进行分页查询的注释是因为PageHelper已经处理了分页逻辑
        Page<BillsDTO> bills = billMapper.selectAllBills(account, bilDTO);

        long total = bills.getTotal();
        List<BillsDTO> records = bills.getResult();

//        BillsDTO dto = new BillsDTO();
//        for (BillsDTO record : records) {
//            dto.setVerificationamount(new BigDecimal(record.getVerificationamount()));
//        }
        return new BillsVO(records,total);
    }

    @Override
    public BillssVO selectAllBill(String account, BilDTO bilDTO) {
        PageHelper.startPage(bilDTO.getPage(),bilDTO.getPageSize());
        Page<BillDTO> bills = billMapper.selectAllBill(account, bilDTO);
        bills.forEach(bill -> {
            String accounttime = bill.getAccounttime();
            LocalDate date = LocalDate.parse(accounttime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String formattedDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            bill.setAccounttime(formattedDate);
        });

        long total = bills.getTotal();
        List<BillDTO> records = bills.getResult();
        return new BillssVO(records,total);
    }

    @Override
    public List<BDTO> selectBasic(BillStatusDTO billStatusDTO) {
        return billMapper.selectBasic(billStatusDTO);
    }

    @Override
    public List<BiDetailsDTO> selectBill(BillStatusDTO billStatusDTO) {
        List<BiDetailsDTO> biDetailsDTOS = billMapper.selectBill(billStatusDTO);
        biDetailsDTOS.forEach(biDetailsDTO -> {
            if (biDetailsDTO.getAccounttime() != null) {
                String accounttime = biDetailsDTO.getAccounttime();
                LocalDate date = LocalDate.parse(accounttime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                String formattedDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM"));
                biDetailsDTO.setAccounttime(formattedDate);
            }
        });
        return biDetailsDTOS;
    }

    @Override
    public List<BillDetailsDTO> selectBillDetails(BillStatusDTO billStatusDTO) {
        List<BillDetailsDTO> billDetailsDTOS = billMapper.selectBillDetails(billStatusDTO);
        billDetailsDTOS.forEach(billDetailsDTO -> {
            if(billDetailsDTO.getFrombilling() != null && billDetailsDTO.getEndofbilling() != null){
                String frombilling = billDetailsDTO.getFrombilling();
                String endofbilling = billDetailsDTO.getEndofbilling();
                LocalDate from = LocalDate.parse(frombilling, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                LocalDate end = LocalDate.parse(endofbilling, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                String formattedDate = from.format(DateTimeFormatter.ofPattern("yyyy-MM"));
                String formattedDate1 = end.format(DateTimeFormatter.ofPattern("yyyy-MM"));
                billDetailsDTO.setFrombilling(formattedDate);
                billDetailsDTO.setEndofbilling(formattedDate1);
            }
        });
        return billDetailsDTOS;
    }

    @Override
    public void updateBill(Integer id) {
        billMapper.updateBill(id);
    }

    @Override
    public void updateLaggold() {
        billMapper.updateLaggold();
    }

    @Override
    public void updateTotalArrears() {
        billMapper.updateTotalArrears();
    }




    //统一收费-应收详情
    public List<ReceivablesVO> getBillByCustomerId(Integer customerId) {
        List<ReceivablesVO> vos = new ArrayList<>();
        //查找客户的账单
        List<Billes> billes = lambdaQuery()
                .eq(Billes::getCustomerid, customerId)
                .eq(Billes::getArrearsstatus, 1)
                .list();
        //账单按照账期
        for (Billes bill : billes) {
            ReceivablesVO vo = new ReceivablesVO();
            //每个账单的账期
            // 格式化账期日期
            LocalDateTime accounttime = bill.getAccounttime();
            // 创建日期格式器
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM");
            // 根据需要选择格式化模式
            String formattedDate = accounttime.format(formatter1);
            vo.setAccounttime(formattedDate);
            //每个账单的账单编号
            Integer billnumber = bill.getBillnumber();
            vo.setBillnumber(billnumber);
            //每个账单的账单详情
            Integer id = bill.getId();
            List<Billdetailes> deatils = billsService.getBillDeatilsByBillIds(id);
            //将详情转换为RecedetailDTO
            List<RecedetailDTO> dtos = BeanUtil.copyToList(deatils, RecedetailDTO.class);
            //将dto转换到vo中
            vo.setRecedetailDTOList(dtos);
            vos.add(vo);
        }
        return vos;
    }


    // 统一收费-应收详情-开始收费
    public CostSummaryVO startCharge(List<Integer> billdetailIds) {
        CostSummaryVO costSummaryVO = new CostSummaryVO();
        //根据id查询账单详情
        List<Billdetailes> billdetails = billsService.getBillDeatilsByids(billdetailIds);
        //将账单详情转换为BillDetailsCostSummaryDTO
        List<BillDetailCostSummaryDTO> billDetailCostSummaryDTOS = BeanUtil.copyToList(billdetails, BillDetailCostSummaryDTO.class);
        costSummaryVO.setBilldetailsListDto(billDetailCostSummaryDTOS);
        //收集billdetails的金额
        List<String> collect = billdetails.stream().map(Billdetailes::getAccountsreceivable).collect(Collectors.toList());
        //计算总金额
        double sum = collect.stream().mapToDouble(Double::parseDouble).sum();

        costSummaryVO.setAccountsreceivableTotal(BigDecimal.valueOf(sum));
        return costSummaryVO;
    }

    @Override
    //统一收费-应收详情-开始收费-确认收费
    public void startChargeConfirm(CostSummaryVO costSummaryVO, Integer customerId, Integer PaymentMethod,Integer useid)  {
        //获取账单详情
        List<BillDetailCostSummaryDTO> billdetailsListDto = costSummaryVO.getBilldetailsListDto();
        Map<Integer, List<BillDetailCostSummaryDTO>> collect = billdetailsListDto.stream().collect(Collectors.groupingBy(BillDetailCostSummaryDTO::getBillid));
        //成功付款后。生成收款记录，改变账单状态和账单详情状态
        List<PaymentRecords> paymentRecords = new ArrayList<>();
        for (Integer i : collect.keySet()) {
            //生成收款记录
            PaymentRecords paymentRecord = new PaymentRecords();
            paymentRecord.setBillid(Long.valueOf(i));
            //获取当前系统时间
              DateTime time = new DateTime();
              paymentRecord.setCollectiontime(time);
              paymentRecord.setPaymentmethodid(Long.valueOf(PaymentMethod));
              //获取每个账单详情的收费金额
            List<BillDetailCostSummaryDTO> billDetailCostSummaryDTOS1 = collect.get(i);
            //计算总的应收收费
            double sum = billDetailCostSummaryDTOS1.stream().map(BillDetailCostSummaryDTO::getAccountsreceivable).mapToDouble(Double::parseDouble).sum();
            BigDecimal bigDecimal = BigDecimal.valueOf(sum);
              paymentRecord.setAmount(bigDecimal);
              paymentRecord.setCustomerid(customerId);
              paymentRecord.setUserid(Long.valueOf(useid));
              paymentRecord.setState(2L);
            //添加到paymentRecords
            paymentRecords.add(paymentRecord);

            //改变账单状态和账单详情状态
            List<BillDetailCostSummaryDTO> billDetailCostSummaryDTOS = collect.get(i);
            List<Integer> billdetailsIds = billDetailCostSummaryDTOS.stream().map(BillDetailCostSummaryDTO::getId).collect(Collectors.toList());
            for (Integer billdetailsId : billdetailsIds) {
                Billdetailes billdetailes = billsService.getById(billdetailsId);
                billdetailes.setAccountsreceivable(String.valueOf(BigDecimal.valueOf(0)));
                billsService.updateById(billdetailes);
            }
        }
        paymentRecordsService.saveBatch(paymentRecords);
    }

    @Override
    public Invoicerecordes getInvoicerecordsByBillid(Integer billid) {
        //根据账单id查询开票记录
        Invoicerecordes invoicerecord = billMapper.getInvoicerecordByBillid(billid);
        return invoicerecord;
    }



    @Override
    public List<Billes> getBillByResourceId(Integer resourceId) {
        String resourceStringId = resourceId.toString();
        List<Billes> billes = billsService.getBillsByResourceid(resourceStringId);
        return billes;
    }


    //统一收费-缴费记录
    @Override
    //缴费历史
    public com.baomidou.mybatisplus.extension.plugins.pagination.Page<PaymentHistoryVO> getPayHistoryByResourceIdPage(Integer resourceid, Integer page, Integer size) {
        // 默认值
        page = (page == null || page <= 0) ? 1 : page;
        size = (size == null || size <= 0) ? 5 : size;
        List<PaymentHistoryVO> vos = new ArrayList<>();
        // 日期格式化器，设置为年月格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
        //分页查询资源id对应的账单详情
        List<Billdetailes> billdetailes = billsService.page(new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size), new QueryWrapper<Billdetailes>()
                .eq("billingresourcesid", resourceid))
                .getRecords();

        //账单详情拿到后，查询公共数据部分（账单、开票），一个（账单和开票）对应多个账单详情
        if(CollUtil.isNotEmpty(billdetailes)){
            for (Billdetailes detail : billdetailes) {
                PaymentHistoryVO vo = new PaymentHistoryVO();
                //查询账单
                Billes bill = getById(detail.getBillid());
                if(bill.getArrearsstatus()==1){
                    //如果状态是1，说明欠费了，不是缴费历史的
                    break;
                }
                //账单封装
                vo.setCustomername(bill.getCustomername());
                String string = bill.getAccounttime().toString();
                vo.setAccounttime(string);
                vo.setBillnumber(detail.getBillid());
                //根据billid查找开票记录信息
                Invoicerecordes invoicerecordes = getInvoicerecordsByBillid(bill.getId());
                // 设置vo开票记录数据
                vo.setInvoicenumber(invoicerecordes.getInvoicenumber());
                vo.setInvoicecode(invoicerecordes.getInvoicecode());
                // 复制账单详情到vo
                BeanUtil.copyProperties(detail, vo);
                vos.add(vo);
            }
        }else {
            // 没有账单
            vos = Collections.emptyList();
        }
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<PaymentHistoryVO> pageHistory = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page,size);
        pageHistory.setRecords(vos);
        pageHistory.setTotal(vos.size());
        return pageHistory;

    }






    @Override
    public int insertB(Billes billes) {
        return billMapper.insertB(billes);
    }

    @Override
    public Billes findByPayee(String payee) {
        return billMapper.findByPayee(payee);
    }

    @Override
    public void update(Billes billes) {
        billMapper.update(billes);
    }

    @Override
    public List<Billes> findUnpaidBillsByCustomerId(int customerid) {
        return billMapper.findUnpaidBillsByCustomerId(customerid);
    }

    @Override
    public Integer isBillOverdue(List<Integer> customerIds) {
        //查询账单
        int size = lambdaQuery()
                .in(Billes::getCustomerid, customerIds)
                .eq(Billes::getArrearsstatus, 1)
                .list()
                .size();
        //1为有欠费的账单，0为没有欠费的账单
        return size>0?1:0;
    }


}
